package com.boot.security.server.service.impl;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.boot.security.server.dto.LoginUser;
import com.boot.security.server.model.Mail;
import com.boot.security.server.service.SendMailSevice;
import com.boot.security.server.utils.Result;
import com.boot.security.server.utils.ResultEnum;
import com.boot.security.server.utils.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.boot.security.server.dao.UserDao;
import com.boot.security.server.dto.UserDto;
import com.boot.security.server.model.SysUser;
import com.boot.security.server.model.SysUser.Status;
import com.boot.security.server.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	private static final Logger log = LoggerFactory.getLogger("adminLogger");

	@Autowired
	private UserDao userDao;
	@Autowired
	private BCryptPasswordEncoder passwordEncoder;
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	@Autowired
	private SendMailSevice sendMailSevice;

	@Override
	@Transactional
	public SysUser saveUser(UserDto userDto) {
		SysUser user = userDto;
		user.setPassword(passwordEncoder.encode(user.getPassword()));
		user.setStatus(Status.VALID);
		userDao.save(user);
		saveUserRoles(user.getId(), userDto.getRoleIds());

		log.debug("新增用户{}", user.getUsername());
		return user;
	}

	private void saveUserRoles(Long userId, List<Long> roleIds) {
		if (roleIds != null) {
			userDao.deleteUserRole(userId);
			if (!CollectionUtils.isEmpty(roleIds)) {
				userDao.saveUserRoles(userId, roleIds);
			}
		}
	}

	@Override
	public SysUser getUser(String username) {
		return userDao.getUser(username);
	}

	@Override
	public void changePassword(String username, String oldPassword, String newPassword) {
		SysUser u = userDao.getUser(username);
		if (u == null) {
			throw new IllegalArgumentException("用户不存在");
		}

		if (!passwordEncoder.matches(oldPassword, u.getPassword())) {
			throw new IllegalArgumentException("旧密码错误");
		}

		userDao.changePassword(u.getId(), passwordEncoder.encode(newPassword));

		log.debug("修改{}的密码", username);
	}

	/**
	 * 注册-邮箱验证码发送
	 * @param mailCode 邮箱地址
	 * @return
	 */
	@Override
	public Result sendMailCode(String mailCode) {
		if (!redisTemplate.hasKey(mailCode)){
			// 生成验证码
			String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
			String code = "" ;
			Random random=new Random();
			StringBuffer sb=new StringBuffer();
			for(int i=0;i<5;i++){
				int number=random.nextInt(62);
				sb.append(str.charAt(number));
			}
			code = sb.toString() ;
			// 发送邮件
			int status = 1;
			String body = "欢迎注册奖状证书生成系统，您的验证码为【"+ code + "】" ;
			try {
				sendMailSevice.sendMail(mailCode, "奖状证书自动生成系统-注册验证码", body);
			} catch (Exception e) {
				log.error("发送邮件失败", e);
				return ResultUtil.error(ResultEnum.MAIL_SEND_ERROR.getCode(),ResultEnum.MAIL_SEND_ERROR.getMsg());
			}
			// 载入redis，并设限制过期时间50秒
			redisTemplate.opsForValue().set(mailCode, code, 60, TimeUnit.SECONDS);
			return ResultUtil.success();
		}else {
			return ResultUtil.error(ResultEnum.MAIL_IS_SEND_ERROR.getCode(),ResultEnum.MAIL_IS_SEND_ERROR.getMsg());
		}
	}

	/**
	 * 邮箱验证码验证接口
	 * @param mail 邮箱
	 * @param code 验证码
	 * @return
	 */
	@Override
	public Result checkingMailCode(String mail,String code) {
		if (redisTemplate.hasKey(mail)){
			if (redisTemplate.opsForValue().get(mail).equals(code)){
				redisTemplate.delete(mail) ;
				return ResultUtil.success( "验证成功" );
			}else {
				return ResultUtil.error(ResultEnum.VERIFICATION_CODE_ERROR.getCode(), ResultEnum.VERIFICATION_CODE_ERROR.getMsg()) ;
			}
		}else {
			return ResultUtil.error(ResultEnum.MAIL_IS_NOT_ERROR.getCode(), ResultEnum.MAIL_IS_NOT_ERROR.getMsg());
		}
	}

	@Override
	@Transactional
	public SysUser updateUser(UserDto userDto) {
		userDao.update(userDto);
		saveUserRoles(userDto.getId(), userDto.getRoleIds());

		return userDto;
	}

}
